<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    /* 
        作用域和自由变量
        闭包
        this指向
    */
    //   作用域
    /* 
    1.全局作用域
    2.函数作用域
    3.块级作用域
 */
    //es6 块级作用域
    // if (true) {
    //   let x = 30;
    // }
    // console.log(x, "x"); //x is not defined
    /* 
     自由变量
     1.一个变量在当前作用域没有定义，但被使用了
     2.向上级作用域，一层层一次寻找，直至找到为止
     3.如果全局作用域都没有，则报错xx is not defined
    */

    /* 
       闭包
    作用域应用的特殊情况，有两种表现：
    1.函数作为参数被传递
    2.函数作为返回值返回
    */
    /* 函数作为返回值 */
    function create() {
      let a = 100;
      return function () {
        console.log(a);
        a++
      };
    }
    let fn = create();
    let a = 200;
    fn();
  
    /* 函数作为参数 */
    function print(fn1) {
      let aa = 200;
      fn1();
    }
    let aa = 100;
    function fn1() {
      console.log(aa);
    }
    print(fn1);

    /* 
        闭包：自由变量的查找，是在函数定义的地方，向上级作用域查找，不是在执行的地方
        函数预解析：函数定义的时候，会预解析函数体中的变量，并将其保存到作用域中，这样就不会再去查找了
        闭包：函数作为参数，或者作为返回值返回，都会使得函数的作用域链发生变化，使得自由变量的查找发生变化

    */
  </script>
</html>
